﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace SaintWinControl
{
    public partial class ucBrowser : UserControl
    {
        /// <summary>
        /// 取回目前的結果，如果有發生錯誤時。
        /// </summary>
        [Category("SaintWinControl")]
        [Description("取回目前的結果，如果有發生錯誤時。把錯誤留下來")]
        public string Message
        {
            get { return message; }
        }

        protected string message = "";
        protected HtmlDocument doc = null;
        public int itest = 0;

        public ucBrowser()
        {
            InitializeComponent();
            webBrowser1.DocumentCompleted += new
                WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);
        }

        void webBrowser1_DocumentCompleted(object sender
            , WebBrowserDocumentCompletedEventArgs e)
        {
            itest++;
            doc = webBrowser1.Document;
        }

        public void BrowserIsReadey()
        {
            while (true)
            {
                System.Threading.Thread.Sleep(1000);
                Application.DoEvents();
                if (webBrowser1.ReadyState == WebBrowserReadyState.Complete)
                {
                    break;
                }
            }
        }

        /// <summary>
        /// 所有要取HtmlDocument 都要從這取，以確定Browser 已經結束
        /// </summary>
        /// <returns></returns>
        public HtmlDocument GetHtmlDocument()
        {
            BrowserIsReadey();
            return doc;
        }

        /// <summary>
        /// 執行網址路徑
        /// </summary>
        /// <param name="address"></param>
        public void NavigateURL(string address)
        {
            if (String.IsNullOrEmpty(address))
            {
                message = "沒有給網址路徑!";
            }
            if (address.Equals("about:blank")) return;
            if (!address.StartsWith("http://") &&
                !address.StartsWith("https://"))
            {
                address = "http://" + address;
            }
            try
            {
                webBrowser1.Navigate(new Uri(address));
                BrowserIsReadey();
            }
            catch (System.UriFormatException ex)
            {
                message = ex.Message;
            }
        }

        /// <summary>
        /// 依Html ID取回 HtmlElement，假設一定會取到HtmlElement，所以設定迴圈
        /// 十次取不到就Exception 出去
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public HtmlElement GetElementByID(string id)
        {
            int i = 0;
            HtmlElement result = null;
            while (i < 10)
            {
                BrowserIsReadey();
                result = doc.GetElementById(id);
                if (result != null)
                { break; }
            }
            if (i.Equals(10))
            { throw new Exception("Can't get HtmlElement in GetElementByID"); }
            return result;
        }

        /// <summary>
        /// 依條件所傳回的集合
        /// </summary>
        /// <param name="elementTagName">EX:input、a HTML的 TAG</param>
        /// <param name="attributeName">EX:name、alt HTML中TAG的屬性</param>
        /// <param name="attributeValues">對應到HTML中TAG的屬性值</param>
        /// <returns></returns>
        public List<HtmlElement> GetElementByName(string elementTagName
            , string attributeName, string[] attributeValues)
        {
            BrowserIsReadey();
            List<HtmlElement> xy = new List<HtmlElement>();
            foreach (HtmlElement input in doc.GetElementsByTagName(elementTagName))
            {
                foreach (string attributeValue in attributeValues)
                {
                    if (input.GetAttribute(attributeName).ToLower().Equals(attributeValue.ToLower()))
                    {
                        xy.Add(input);
                    }
                }
            }
            return xy;
        }

        /// <summary>
        /// 找出要設定的Element，並把value 填上
        /// </summary>
        /// <param name="p_elementTag">EX:input、a HTML的 TAG</param>
        /// <param name="p_attributeName">Html中的Attribute</param>
        /// <param name="p_inputDict">Key:Attribute中的Value；Value：input中的Value</param>
        public void SetElementValueByName(string p_elementTag
            , string p_attributeName, Dictionary<string, string> p_inputDict)
        {
            HtmlElementCollection inputs = GetElementsByTag(p_elementTag);
            foreach (HtmlElement input in inputs)
            {
                foreach (KeyValuePair<string, string> kv in p_inputDict)
                {
                    if (input.GetAttribute(p_attributeName).ToLower()
                        .Equals(kv.Key.ToString()))
                    {
                        input.SetAttribute("value", kv.Value.ToString());
                    }
                }
            }
        }

        /// <summary>
        /// 確定一定會取得HtmlElementCollection
        /// </summary>
        /// <param name="p_tag"></param>
        /// <returns></returns>
        public HtmlElementCollection GetElementsByTag(string p_tag)
        {
            int i = 0;
            HtmlElementCollection result = null;
            while (i < 10)
            {
                BrowserIsReadey();
                result = doc.GetElementsByTagName(p_tag);
                if (result != null)
                { break; }
            }
            if (i.Equals(10))
            {
                throw new Exception(
                  "Can't get HtmlElementCollection in getElementsByTag");
            }
            return result;
        }

        public string GetBrowseState()
        {
            return webBrowser1.StatusText;
        }

        public void ElementInvok(HtmlElement html, string invokeMethod)
        {
            //webBrowser1.Document.DomDocument            
            //html.RaiseEvent("onclick");
            html.InvokeMember(invokeMethod);
            BrowserIsReadey();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="p_elementTagName"></param>
        /// <param name="p_attributeName"></param>
        /// <param name="p_attributeValues"></param>
        /// <param name="p_invokeMethod"></param>
        public void ElementInvok(string p_elementTagName, string p_attributeName
            , string[] p_attributeValues, string p_invokeMethod)
        {
            List<HtmlElement> al = GetElementByName(
                p_elementTagName, p_attributeName, p_attributeValues);
            HtmlElement html = al[0] as HtmlElement;
            ElementInvok(html, p_invokeMethod);
        }

        public string GetCurrentURL()
        {
            return webBrowser1.Url.ToString();
        }

        /// <summary>
        /// 傳入HTML中Table的ID，回傳一個DataTable
        /// </summary>
        /// <param name="p_id"></param>
        /// <param name="p_dt">傳入已定義好的Table</param>
        /// <param name="p_pos">HtmlTable 中要取的column 位置</param>
        /// <returns></returns>
        public DataTable GetDataByHtmlTable(string p_id, DataTable p_dt, int[] p_pos)
        {
            HtmlElement table = GetElementByID(p_id);
            HtmlElementCollection trCollect = table.GetElementsByTagName("tr");
            //避掉Row1是標題，所以從1開始取值
            for (int i = 1; i < trCollect.Count; i++)
            {
                HtmlElementCollection tdCollect = trCollect[i]
                    .GetElementsByTagName("td");
                DataRow row = p_dt.NewRow();
                int x = 0;
                if (tdCollect.Count > 1)
                {
                    foreach (int pos in p_pos)
                    {
                        row[x] = tdCollect[pos].InnerText;
                        x++;
                    }
                    p_dt.Rows.Add(row);
                }
            }
            return p_dt;
        }
    }
}
